package sky.market.console.util;


import cn.hutool.core.date.DateUtil;
import com.cronutils.descriptor.CronDescriptor;
import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;

public class CronUtils {

    public static void main(String[] args) {
        String expression = "0 0/30 * * * ? *";
        System.out.println(describeCron(expression));
        System.out.println(parseCronToExeTime(expression));
        System.out.println(parseCronToLastTime(expression, DateUtil.offsetDay(new Date(), 3)));
        //格式校验
        boolean b = checkCronValid(expression);
        System.out.println(b);
    }

    public static String describeCron(String expression) {
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
        CronParser parser = new CronParser(cronDefinition);
        Cron cron = parser.parse(expression);
        //设置语言
        CronDescriptor descriptor = CronDescriptor.instance(Locale.CHINESE);
        return descriptor.describe(cron);
    }


    public static String parseCronToExeTime(String expression) {
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
        CronParser parser = new CronParser(cronDefinition);
        Cron cron = parser.parse(expression);
        ExecutionTime exeTime = ExecutionTime.forCron(cron);
        ZonedDateTime now = ZonedDateTime.now();
        //根据当前时间获取下次执行时间
        ZonedDateTime next = exeTime.nextExecution(now).get();
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

        return next.format(format);
    }


    public static boolean checkCronValid(String cron) {
        try {
            CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
            CronParser parser = new CronParser(cronDefinition);
            parser.parse(cron);
        } catch (IllegalArgumentException e) {
            return false;
        }
        return true;
    }


    public static Date parseCronToLastTime(String expression, Date endTime) {
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
        CronParser parser = new CronParser(cronDefinition);
        Cron cron = parser.parse(expression);
        ExecutionTime exeTime = ExecutionTime.forCron(cron);
        ZoneId zone = ZoneId.systemDefault();
        Optional<ZonedDateTime> optional = exeTime.lastExecution(endTime.toInstant().atZone(zone));
        return Date.from(optional.get().toInstant());
    }
}

